package com.countertack.smoke;

import java.io.File;
import java.io.FileOutputStream;
import java.net.InetAddress;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.UUID;

import org.doublecloud.vi.vmware.guest.GuestProcessDirector;

import com.countertack.impala.ImpalaConnector;
import com.countertack.ssh.SSHManager;
import com.countertack.utils.Configuration;
import com.countertack.utils.HttpClientUtils;
import com.countertack.vmware.VMWareConnector;
import com.countertack.vmware.VMWareUtils;
import com.vmware.vim25.mo.VirtualMachine;

public class SmokeTest {

	public static void main(String[] args) throws Exception {
		StringBuffer testCaseResult = new StringBuffer();
		ImpalaConnector iConnector = null;
		VMWareConnector esxiConnector = null;

		try {
			if (args.length <= 0) {

				System.out.println("configuration details missed !");
				return;
			}
			String configFilePath = args[0];

			// String configFilePath =
			// "C:\\Users\\user\\Desktop\\config.properties";
			// String configFilePath = "config.properties";
			String uuid = UUID.randomUUID().toString();
			Configuration.loadProperties(configFilePath);

			String vmUser = Configuration.getProperty("vmuser");
			String vmPassword = Configuration.getProperty("vmpassword");
			boolean isXpmachine = false;

			iConnector = new ImpalaConnector();
			iConnector.createImpalaConnection(Configuration
					.getProperty("sentinelehost"));

			InetAddress address = InetAddress.getByName(Configuration
					.getProperty("sentinelehost"));
			String sentenelIp = address.getHostAddress();
			System.out.println(address.getHostAddress());
			// connect to esxi and starting virtual machines

			esxiConnector = new VMWareConnector(
					Configuration.getProperty("esxi"));

			final VirtualMachine endPointMachine = esxiConnector
					.getVirtualMachineByname(Configuration
							.getProperty("vmname"));

			System.out.println("power state >>>"
					+ endPointMachine.getRuntime().powerState);

			String smokeSnapShotName = Configuration
					.getProperty("rootsnapshotname");
			esxiConnector.revertToSnapShort(endPointMachine.getSnapshot()
					.getRootSnapshotList(), smokeSnapShotName);

			System.out.println("Reverting to root snap shot>>>>>"
					+ smokeSnapShotName);

			Thread.sleep(180000);

			String osType = VMWareUtils.getVMOSArchitecture(
					Configuration.getProperty("esxi"),
					Configuration.getProperty("vmname"));
			testCaseResult.append("OS>>>>" + osType + "\n");
			if (osType != null) {

				osType = osType.toLowerCase();

				if (osType.contains("xp")) {

					isXpmachine = true;
				}
			}

			esxiConnector.checkAndRunVirtualMachine(endPointMachine);

			GuestProcessDirector progDir = new GuestProcessDirector(
					endPointMachine, vmUser, vmPassword);

			progDir.run("C:\\Windows\\System32\\cmd.exe",
					"/c mkdir C:\\Users\\user");

			if (isXpmachine) {

				progDir.run("C:\\Windows\\System32\\cmd.exe",
						"/c copy C:\\Windows\\System32\\cmd.exe \"C:\\Documents and Settings\\"
								+ vmUser + "\\cmd.exe\"");
			} else {

				progDir.run("C:\\Windows\\System32\\cmd.exe",
						"/c copy C:\\Windows\\System32\\cmd.exe C:\\Users\\"
								+ vmUser + "\\cmd.exe");
			}

			// initialising ssh to virtual machines
			String vmIp = Configuration.getProperty("vmip");
			if (vmIp == null || vmIp.trim() == "") {

				vmIp = endPointMachine.getGuest().ipAddress;
			}
			System.out.println("ip>>>" + endPointMachine.getGuest().ipAddress);

			final SSHManager endpointSsh = new SSHManager(vmUser, vmPassword,
					vmIp);
			endpointSsh.connect();
			testCaseResult.append("VM NAME>>>>"
					+ Configuration.getProperty("vmname") + "\n");
			testCaseResult.append("VM IP>>>"
					+ endPointMachine.getGuest().ipAddress + "\n");
			testCaseResult.append("Sentinel  IP>>>" + sentenelIp + "\n");

			// install agent

			endpointSsh.copyFile(Configuration.getProperty("driverpath"),
					"CounterTack Agent Installer Hiding.exe");
			if (isXpmachine) {
				endpointSsh
						.runCommand("cmd /c \"C:\\Documents and Settings\\"
								+ vmUser
								+ "\\CounterTack Agent Installer Hiding.exe\" /S /HOST:"
								+ sentenelIp + " /PORT:443");

			} else {

				endpointSsh
						.runCommand("cmd /c \"C:\\Users\\"
								+ vmUser
								+ "\\CounterTack Agent Installer Hiding.exe\" /S /HOST:"
								+ sentenelIp + " /PORT:443");

			}

			System.out.println("Installing agent on endpoint");
			Thread.sleep(120000);

			String eId = null;
			ResultSet endpointIdRes = iConnector
					.executeQueryAndReturnResults("select id from endpoints where ip='"
							+ vmIp
							+ "'"
							+ " and status='ON' and ip is not null order by time_started desc limit 1");

			while (endpointIdRes.next()) {
				try {
					eId = endpointIdRes.getString(1);
				} catch (Exception e) {

				}

				System.out.println("endpoint Id>>>>>>" + eId);
				testCaseResult.append("endpoint Id>>>>>>" + eId + "\n");

			}

			if (eId == null) {

				System.out.println("endpoint is not installed");
				testCaseResult.append("endpoint is not installed \n");
				// addResultsToLog(testCaseResult);
				System.exit(0);

			}
			String driverVersion = getDriverVersion(eId, iConnector);
			testCaseResult.append("Kernal Module Version  >>>" + driverVersion
					+ "\n");
			pauseEndpoint(eId);
			Thread.sleep(60000);

			resumeEndpoint(eId);
			Thread.sleep(60000);
			if (isXpmachine) {
				progDir.run(
						"C:\\Documents and Settings\\" + vmUser + "\\cmd.exe",
						"/c ipconfig > \"c:\\Documents and Settings\\"
								+ vmUser
								+ "\\vmwaretest1.txt\" && sc query && arp -a && echo \"hello world\" > \"c:\\Documents and Settings\\"
								+ vmUser
								+ "\\smoketestfile"
								+ uuid
								+ ".txt\" && reg  add HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\services\\smoketestkey_"
								+ uuid);

			} else {
				progDir.run(
						"C:\\Users\\" + vmUser + "\\cmd.exe",
						"/c ipconfig > c:\\Users\\"
								+ vmUser
								+ "\\vmwaretest1.txt && sc query && arp -a && echo \"hello world\" >  c:\\Users\\"
								+ vmUser
								+ "\\smoketestfile"
								+ uuid
								+ ".txt && reg  add HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\services\\smoketestkey_"
								+ uuid);

			}

			Thread.sleep(120000);

			ResultSet brs = iConnector
					.executeQueryAndReturnResults("select hex(id) from behaviors where uri like '%"
							+ eId
							+ "%'  order by event_start_time desc limit 1");
			String bhid = null;

			while (brs.next()) {
				bhid = brs.getString(1);

			}
			System.out.println("behavior id>>>>" + bhid);
			testCaseResult.append("behavior id>>>>" + bhid + "\n");

			// verifying process
			ResultSet proResset = iConnector
					.executeQueryAndReturnResults("select target_process_name from behaviors_denorm where hex(behavior_id) = '"
							+ bhid
							+ "' and behavior_id is not null and action = 'PROCESS_CREATE' limit 10");

			boolean verProce = false;
			while (proResset.next()) {
				String prosNmae = proResset.getString(1);

				if (prosNmae != null) {

					System.out.println("ProcessName>>>" + prosNmae);
					testCaseResult.append("ProcessName>>>" + prosNmae + "\n");
					if (prosNmae.contains("cmd")
							|| prosNmae.contains("ipconfig")
							|| prosNmae.contains("netstat")
							|| prosNmae.contains("tasklist")) {

						// System.out.println("Inbound passed");
						verProce = true;

						// System.exit(0);
						// return;

					}

				}
			}

			if (verProce) {

				System.out.println("Verifying process---------->Pass");
				testCaseResult.append("Verifying process---------->Pass \n");

			} else {

				System.out.println("Verifying process---------->Fail");
				testCaseResult.append("Verifying process---------->Fail \n");
				// System.exit(0);

			}

			// verifying file creation

			ResultSet flCrResSet = iConnector
					.executeQueryAndReturnResults("select target_file_path from behaviors_denorm where hex(behavior_id) = '"
							+ bhid
							+ "' and behavior_id is not null group by target_file_path");

			boolean verfile = false;
			while (flCrResSet.next()) {
				String fileNmae = flCrResSet.getString(1);

				if (fileNmae != null) {

					System.out.println("FileName>>>" + fileNmae);
					testCaseResult.append("FileName>>>" + fileNmae + "\n");
					if (fileNmae.contains("smoketestfile")) {

						// System.out.println("Inbound passed");
						verfile = true;

						// System.exit(0);
						// return;

					}

				}
			}

			if (verfile) {

				System.out.println("Verifying file---------->Pass");
				testCaseResult.append("Verifying file---------->Pass \n");

			} else {

				System.out.println("Verifying file---------->Fail");
				testCaseResult.append("Verifying file---------->Fail \n");
				// System.exit(0);

			}

			ResultSet regResset = iConnector
					.executeQueryAndReturnResults("select target_registry_key from behaviors_denorm where hex(behavior_id) = '"
							+ bhid
							+ "' and behavior_id is not null group by target_registry_key limit 10");

			boolean verReg = false;
			while (regResset.next()) {
				String regNmae = regResset.getString(1);

				if (regNmae != null) {

					System.out.println("RegName>>>" + regNmae);
					testCaseResult.append("RegName>>>" + regNmae + "\n");
					if (regNmae.contains("smoketestkey")) {

						// System.out.println("Inbound passed");
						verReg = true;

						// System.exit(0);
						// return;

					}

				}
			}

			if (verReg) {

				System.out.println("Verifying regestry---------->Pass");
				testCaseResult.append("Verifying regestry---------->Pass \n");

			} else {

				System.out.println("Verifying regestry---------->Fail");
				testCaseResult.append("Verifying regestry---------->Fail \n");
				// System.exit(0);

			}

		} finally {

			try {
				if (iConnector != null) {
					iConnector.closeImpalaConnection();
				}
			} catch (Exception e) {

				e.printStackTrace();
			}

			try {
				if (esxiConnector != null) {

					esxiConnector.closeEsxiConnection();
				}

			} catch (Exception e) {

				e.printStackTrace();
			}

			addResultsToLog(testCaseResult);

		}

	}

	public static void addResultsToLog(StringBuffer vals) {
		File testCaseResFile = new File("Smoketest_result_"
				+ Configuration.getProperty("vmname") + ".txt");

		try {
			testCaseResFile.createNewFile();
			FileOutputStream fout = new FileOutputStream(testCaseResFile);

			//

			fout.write(vals.toString().getBytes());

			fout.flush();
			fout.close();

		} catch (Exception e) {

			e.printStackTrace();

		}

	}

	public static void pauseEndpoint(String eid) throws Exception {

		String pause = "{ " + "  \"type\":\"pause_many\", "
				+ "  \"endpoints\":[ " + "\"" + eid + "\" " + " ] " + "} ";

		HttpClientUtils.composePostRequest(
				Configuration.getProperty("restapirooturi")
						+ "/endpoints/command", pause);

	}

	public static void resumeEndpoint(String eid) throws Exception {

		String resume = "{ " + "  \"type\":\"resume_many\", "
				+ "  \"endpoints\":[ " + "    \"" + eid + "\" " + "] " + "} ";

		HttpClientUtils.composePostRequest(
				Configuration.getProperty("restapirooturi")
						+ "/endpoints/command", resume);

	}

	public static String getDriverVersion(String eid, ImpalaConnector iConnector) {

		String driver_Version = null;
		ResultSet endpointStatRes = iConnector
				.executeQueryAndReturnResults("select driver_version from endpoints where id='"
						+ eid + "'");
		try {
			while (endpointStatRes.next()) {
				try {
					driver_Version = endpointStatRes.getString(1);
				} catch (Exception e) {

				}

				System.out.println("Driver version>>>>>>" + driver_Version);

			}
		} catch (Exception e) {

		}

		return driver_Version;

	}

}
